﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MapViewer
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			InitializeComponent();
		}

		private void fileName_MouseEnter(object sender, MouseEventArgs e)
		{
			(Resources["FileLeave"] as System.Windows.Media.Animation.Storyboard).Stop();
			this.BeginStoryboard(Resources["FileEnter"] as System.Windows.Media.Animation.Storyboard);
		}

		private void fileName_MouseLeave(object sender, MouseEventArgs e)
		{
			(Resources["FileEnter"] as System.Windows.Media.Animation.Storyboard).Stop();
			this.BeginStoryboard(Resources["FileLeave"] as System.Windows.Media.Animation.Storyboard);
		}

		private void MenuItem_Click(object sender, RoutedEventArgs e)
		{
			MenuItem element = sender as MenuItem;
			Model.RecentItem item = element.DataContext as Model.RecentItem;
			LoadItemAsync(item);
		}

		private void OpenFile()
		{
			Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
			ofd.CheckFileExists = true;
			ofd.CheckPathExists = true;
			ofd.DefaultExt = "dat";
			ofd.DereferenceLinks = true;
			ofd.Filter = "Named Binary Tag Map Files|map_*.dat";
			ofd.FilterIndex = 0;
			ofd.Multiselect = false;
			ofd.ShowReadOnly = false;
			ofd.Title = "Select a map File.";
			if (ofd.ShowDialog() == true)
			{
				Model.RecentItem item = new Model.FileRecentItem() { FilePath = ofd.FileName };
				LoadItemAsync(item);
			}
		}

		private void OpenFolder()
		{
			Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
			ofd.CheckFileExists = false;
			ofd.CheckPathExists = true;
			ofd.Filter = "Named Binary Tag Map Files|map_*.dat";
			ofd.FilterIndex = 0;
			ofd.Multiselect = false;
			ofd.ShowReadOnly = false;
			ofd.Title = "Select a folder containing map files.";
			ofd.FileName = "Current folder";
			ofd.FileOk += (sender1, e1) => {
				if (System.IO.Directory.GetFiles(System.IO.Path.GetDirectoryName(ofd.FileName), "map_*.dat", System.IO.SearchOption.TopDirectoryOnly).Length == 0)
				{
					MessageBox.Show("Selected folder does not contains Map files.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
					e1.Cancel = true;
				}
			};
			if (ofd.ShowDialog() == true)
			{
				Model.RecentItem item = new Model.FolderRecentItem() { FolderPath = System.IO.Path.GetDirectoryName(ofd.FileName) };
				LoadItemAsync(item);
			}
		}

		private void OpenUrl()
		{
			ServerNavWindow nav = new ServerNavWindow();
			this.Visibility = System.Windows.Visibility.Hidden;
			bool? result = nav.ShowDialog();
			this.Visibility = System.Windows.Visibility.Visible;
			if (result == true)
			{
				Model.RecentItem item = new Model.UrlRecentItem() { Url = nav.Url };
				LoadItemAsync(item);
			}
		}

		private void LoadItemAsync(Model.RecentItem item)
		{
			LoadPane.Visibility = System.Windows.Visibility.Visible;
			(Resources["LoadingAnimation"] as System.Windows.Media.Animation.Storyboard).Begin();
			System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
			worker.DoWork += delegate
			{
				LoadItem(item);
			};
			worker.RunWorkerAsync();
		}

		private void LoadItem(Model.RecentItem item)
		{
			object[] attributes = item.GetType().GetCustomAttributes(typeof(Loaders.LoaderTypeAttribute), false);
			if (attributes.Length == 1)
			{
				Loaders.ILoader loader = (attributes[0] as Loaders.LoaderTypeAttribute).Instance;
				loader.Load(delegate(NamedBinaryTag.TagFile target)
				{
					Application.Current.Dispatcher.BeginInvoke(new Action(delegate
					{
						(Resources["SourceFile"] as NamedBinaryTag.TagFile).Swap(target);
						fileName.Text = item.Title;
						UpdateRecent(item);
					}));
				}, item);
			}
			else
			{
				Application.Current.Dispatcher.BeginInvoke(new Action(delegate
				{
					MessageBox.Show("Unable to load selected data.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
				}));
			}
			Application.Current.Dispatcher.BeginInvoke(new Action(delegate
			{
				LoadPane.Visibility = System.Windows.Visibility.Hidden;
				(Resources["LoadingAnimation"] as System.Windows.Media.Animation.Storyboard).Stop();
			}));
		}

		private void UpdateRecent(Model.RecentItem newItem)
		{
			int max = MapViewer.Properties.Settings.Default.MaxRecent;
			RecentItemsCollection items = App.Current.Resources["RecentItems"] as RecentItemsCollection;
			if (items.Contains(newItem))
			{
				items.Remove(newItem);
			}
			items.Insert(0, newItem);
			while (items.Count > max)
			{
				items.RemoveAt(max);
			}
		}

		private void Recent_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			Model.RecentItem item = e.Parameter as Model.RecentItem;
			LoadItemAsync(item);
		}

		private void Recent_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void RecentMenu_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = (App.Current.Resources["RecentItems"] as RecentItemsCollection).Count > 0;
		}

		private void Open_CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = true;
		}

		private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
		{
			if (e.Parameter == null)
			{
				OpenFile();
				return;
			}
			String action = e.Parameter as String;
			if (action == "File") OpenFile();
			if (action == "Folder") OpenFolder();
			if (action == "Url") OpenUrl();
		}
	}
}
